package com.cloud.config.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.cloud.constant.SystemConstant;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by cRyann on 2017/3/13.
 */
@Configuration
public class ShiroConfiguration {
    private static Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

    @Bean
    public UserRealm shiroRealm() {
        UserRealm myUserRealm = new UserRealm();
        myUserRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        //启用缓存
        myUserRealm.setCachingEnabled(true);
        myUserRealm.setAuthenticationCachingEnabled(true);
        myUserRealm.setAuthorizationCachingEnabled(true);
        //认证缓存
        myUserRealm.setAuthenticationCacheName("authenticationCache");
        //授权缓存
        myUserRealm.setAuthorizationCacheName("authorizationCache");
        return myUserRealm;
    }

    /**
     * rememberMe 记住我 cokie设置
     *
     * @return
     */
    @Bean
    public SimpleCookie rememberMeCokie() {
        SimpleCookie simpleCookie = new SimpleCookie();
        simpleCookie.setMaxAge(SystemConstant.COKIE_TIMEOUT);
        simpleCookie.setName("rememberMe");
        return simpleCookie;
    }

    /**
     * 记住我管理器
     *
     * @return
     */
    @Bean
    public CookieRememberMeManager cookieRememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCokie());
        return cookieRememberMeManager;
    }

    @Bean
    public EhCacheManager ehCacheManager() {
        EhCacheManager em = new EhCacheManager();
        em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
        return em;
    }

    @Bean
    public RetryLimitHashedCredentialsMatcher getRetryLimitHashedCredentialsMatcher() {
        return new RetryLimitHashedCredentialsMatcher(ehCacheManager());
    }

    @Bean
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }

    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
        dwsm.setRealm(shiroRealm());
        dwsm.setCacheManager(ehCacheManager());
        //注入记住我管理器;
        dwsm.setRememberMeManager(cookieRememberMeManager());
        return dwsm;
    }

    /**
     * 开启shir权限注解
     *
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
        aasa.setSecurityManager(securityManager());
        return new AuthorizationAttributeSourceAdvisor();
    }
    @Bean
    public DefaultWebSessionManager sessionManager(){
        SessionManager sessionManager=new SessionManager();
        sessionManager.setCacheManager(ehCacheManager());
        return sessionManager;
    }
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        shiroFilterFactoryBean.setLoginUrl("/login");
        filterChainDefinitionMap.put("/logout", "logout");
        //filterChainDefinitionMap.put("/", "user");
        filterChainDefinitionMap.put("/login", "anon");
        //filterChainDefinitionMap.put("/users/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
    /**
     * 凭证匹配器
     *
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new RetryLimitHashedCredentialsMatcher(ehCacheManager());
        //散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        //散列的次数，比如散列两次，相当于 md5(md5(""));
        hashedCredentialsMatcher.setHashIterations(2);
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        return hashedCredentialsMatcher;
    }
}
